﻿using System;
using System.ServiceModel;
using nRoute.Components.Composition;
using Orktane.Components;
using Orktane.Sample.ConsoleApp.Services;
using Orktane.ScriptActionModel;

namespace Orktane.Sample.ConsoleApp.ScriptActions
{
    [MapScriptAction("STOP-PROCESS", "Stop Process", ShortDescription = "Stops the specified process (id) on the remote machine",
        Lifetime = InstanceLifetime.PerInstance)]
    public class StopProcessScriptAction
        : IConsoleScriptAction
    {
        private const string ECLIPSE = "...";
        private const string SPACE = " ";

        private RemoteProcessesServiceClient _remoteProcessesService;
        private IConsole _console;
        private IDisposable _completionToken;

#region IConsoleScriptAction Members

        public void Intialize(IConsole console, IDisposable completionToken)
        {
            if (console == null) throw new ArgumentNullException("console");
            if (completionToken == null) throw new ArgumentNullException("completionToken");

            _console = console;
            _completionToken = completionToken;
        }

        public void Execute(Arguments args)
        {
            int _processId;
            if (args == null || string.IsNullOrWhiteSpace(args.CommandLine))
            {
                _console.WriteLine("Please specify the process id to stop on the remote machine");
                _completionToken.Dispose();
            }
            else if (Int32.TryParse(args.CommandLine, out _processId))
            {
                _remoteProcessesService = new RemoteProcessesServiceClient();
                _remoteProcessesService.StopProcessCompleted += new EventHandler<StopProcessCompletedEventArgs>(Service_StopProcessCompleted);
                _remoteProcessesService.StopProcessAsync(_processId);
                _console.DisableInput = true;
            }
            else
            {
                _console.WriteLine("Invalid process id, please specify a valid process id to stop");
                _completionToken.Dispose();
            }
        }

        public bool Cancel()
        {
            if (_remoteProcessesService != null &&
                (_remoteProcessesService.State == CommunicationState.Opened || _remoteProcessesService.State == CommunicationState.Opening))
            {
                _remoteProcessesService.Abort();
            }

            _console.WriteLine("Cancelled Stop-Process..");
            return true;
        }

        public void Close()
        {
            if (_remoteProcessesService == null) return;
            
            if (_remoteProcessesService.State != CommunicationState.Closed && _remoteProcessesService.State != CommunicationState.Closing)
            {
                _remoteProcessesService.CloseAsync();
            }
            _remoteProcessesService.StopProcessCompleted -= new EventHandler<StopProcessCompletedEventArgs>(Service_StopProcessCompleted);
            _remoteProcessesService = null;
            _console.DisableInput = false;          
        }

#endregion

#region Handlers

        private void Service_StopProcessCompleted(object sender, StopProcessCompletedEventArgs e)
        {
            if (!e.Cancelled && e.Error == null)
            {
                _console.WriteLine(e.Result ? "Process Stopped" : "Process could not be stopped.");
            }
            else
            {
                if (e.Error != null)
                {
                    _console.Write("An Error Occurred: ");
                    _console.WriteLine(e.Error.Message);
                    _console.WriteLine();
                    _console.WriteLine(e.Error.StackTrace);
                }
                else
                {
                    _console.WriteLine("Script command was cancelled");
                }
            }

            _console.WriteLine();
        
            // and indicate that we have completed
            _completionToken.Dispose();
        }

#endregion

    }
}